package com.rd.sys.action.analysis;

import com.rd.sys.action.BaseAction;
import com.rd.sys.common.FileUtil;
import com.rd.sys.common.ReportAoiData;
import com.rd.sys.common.base.CommonConstants;
import com.rd.sys.common.utils.JacksonMapper;
import com.rd.sys.common.utils.client.AnalysisPathUtils;
import com.rd.sys.dto.client.analysis.AoiData;
import com.rd.sys.dto.client.analysis.SchemeResultData;
import com.rd.sys.dto.client.analysis.config.AnalysisConfig;
import com.rd.sys.dto.client.store.*;
import com.rd.sys.dto.sys.user.UserInfoDto;
import com.rd.sys.service.analysis.event.EventService;
import com.rd.sys.service.analysis.project.ProjectService;
import com.rd.sys.service.analysis.result.ResultService;
import com.rd.sys.service.analysis.scheme.SchemeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.*;

public class AnalysisAction extends BaseAction {

    private static final long serialVersionUID = 4593145139131289308L;

    // -------------------------------------以下是数据成员定义-------------------------------------------
    /**
     * 返回导出AOI报告的视图
     *
     * @return
     * @throws Exception
     */

    List<Question> questionList;
    Map<String, Object> kv;
    @Autowired
    private ProjectService projectService;
    @Autowired
    private SchemeService schemeService;
    @Autowired
    private ResultService resultService;
    @Autowired
    private EventService eventService;
    private List<Project> projectList;
    private String projectName; // 项目名称(查询条件)
    private String projectCode;
    private String schemeCode;
    private String resultCode;
    private String materialCode;
    private List<Material> materialList;
    private Scheme scheme;
    private List<AoiData> aoiGraphsList;
    private String theSource; // 请求来源: 客户端 or 浏览器（服务端）
    private List<AnalysisConfig> configList; // 绘图配置参数
    private List<Map<String, Object>> reportList; // 绘图配置参数
    private String alreadyCheckboxs; // 已选中的结果(此处只用于客户端传递过来时，直接在页面中绘制选中的结果，当前只会有1个结果)
    private String alreadyRadio; // 单选中的结果

    // ------------------------------------------以下是业务方法------------------------------------------
    private List<Result> resultList;// 结果信息
    /**
     * 1：已经下载，0：未下载
     */
    private int hasLoad = 0;

    /**
     * 普通访问的分析首页
     *
     * @return
     */
    public String index() {
        projectList = projectService.queryProjectList(this.getUser(request).getUsercode(), projectName);

        if (CommonConstants.UserConstats.USER_THE_CLIENT_SOURCE.equals(theSource)) {
            return indexClient();
        }
        return "toProjectServer";
    }

    /**
     * 客户端的分析首页
     *
     * @return
     */
    public String indexClient() {
        return "toProjectClient";

    }

    /**
     * 普通访问的方案首页
     *
     * @return
     */
    public String scheme() throws Exception {
        scheme = schemeService.queryScheme(this.getUser(request).getUsercode(), projectCode, schemeCode);
        aoiGraphsList = schemeService.queryAoiData(this.getUser(request).getUsercode(), projectCode, schemeCode);

        if (CommonConstants.UserConstats.USER_THE_CLIENT_SOURCE.equals(theSource)) {
            return schemeClient();
        }
        return "toSchemeServer";
    }

    /**
     * 客户端的方案首页
     *
     * @return
     */
    public String schemeClient() throws Exception {
        // 检查是否下载过渲染结果
//        String path = AnalysisPathUtils.findSchemePath(this.getUser(request).getUsercode(),projectCode,schemeCode);
//        File file = new File(path);
//        if (file.exists()){
//            File[] files = FileUtil.orderByDate(file);
//            if (files.length > 0){
//                File f = new File(files[0].getPath() +CommonConstants.SysParamConstants.FILE_SEPARATOR+"data"+CommonConstants.SysParamConstants.FILE_SEPARATOR);
//                if ( f.exists()){
//                    File[] arrFiles = f.listFiles();
//                    if (arrFiles != null && arrFiles.length > 7){
//                        hasLoad = 1;
//                    }
//                }
//            }
//        }

        if (StringUtils.isNotBlank(resultCode)) {
            Integer index = resultService.queryResultIndex(this.getUser(request).getUsercode(), projectCode,
                    schemeCode, resultCode);
            if (index != null) {
                alreadyCheckboxs = String.valueOf(index);
            }
        }
        return "toSchemeClient";
    }

    /**
     * 获取方案下未下载过的素材列表
     */
    public void findM() throws IOException {
        Map<String, Object> reMap = new HashMap<String, Object>();
        // 检查是否配置了需要下载素材
        boolean isLoad = false;
        String basePath = AnalysisPathUtils.getUserBasePath();
        try {
            FileInputStream fis = new FileInputStream(basePath + "config.properties");
            Properties properties = new Properties();
            properties.load(fis);
            String autoDownload = properties.getProperty("autoDownload", "0");
            if (autoDownload.equalsIgnoreCase("0")) {
                isLoad = false;
            } else if (autoDownload.equalsIgnoreCase("1")) {
                isLoad = true;
            } else {
                isLoad = false;
            }
            fis.close();
        } catch (Exception e) {
            isLoad = false;
        }

        if (isLoad) {
            String path = AnalysisPathUtils.findSchemePath(this.getUser(request).getUsercode(), projectCode, schemeCode);
            List<Material> list = schemeService.queryMaterialList(this.getUser(request).getUsercode(), projectCode, schemeCode);
            File file = new File(path);
            List<Material> materials = new ArrayList<Material>();
            if (file.exists()) {
                File[] files = FileUtil.orderByDate(file);
                if (files.length > 0) {
                    File f = new File(files[files.length - 1].getPath() + CommonConstants.SysParamConstants.FILE_SEPARATOR +
                            "data" + CommonConstants.SysParamConstants.FILE_SEPARATOR);
                    if (f.exists()) {
                        File[] ms = f.listFiles();
                        materials.addAll(FileUtil.isContains(ms, list));
                    } else {
                        materials.addAll(list);
                    }
                }
            }
            reMap.put("data", FileUtil.reset(materials));
            setJsonFormat();
            response.setStatus(200);
            response.getWriter().write(JacksonMapper.bean2Json(reMap));
        } else {
            reMap.put("data", new ArrayList<Object>());
            setJsonFormat();
            response.setStatus(200);
            response.getWriter().write(JacksonMapper.bean2Json(reMap));
        }
    }

    /**
     * heat map
     *
     * @return
     */
    public String heatmap() {
        configList = AnalysisConfig.heatConfigList;
        return "toHeatmap";
    }

    /**
     * route map
     *
     * @return
     */
    public String routemap() {
        configList = AnalysisConfig.routeConfigList;
        return "toRoutemap";
    }

    /**
     * focus map
     *
     * @return
     */
    public String focusmap() {
        configList = AnalysisConfig.focusConfigList;
        return "toFocusmap";
    }

    /**
     * grid map
     *
     * @return
     */
    public String gridmap() {
        configList = AnalysisConfig.gridConfigList;
        return "toGridmap";
    }

    /**
     * AOI
     *
     * @return
     */
    public String aoi() {
        configList = AnalysisConfig.aoiConfigList;
        return "toAreaOfInterest";
    }

    /**
     * 弹窗选择素材
     *
     * @return
     */
    public String popMaterial() {
        materialList = schemeService.queryMaterialList(this.getUser(request).getUsercode(), projectCode, schemeCode);

        return "toPopMaterial";
    }

    /**
     * 加载素材信息&原始数据
     */
    public void loadMaterialAndRawData() throws Exception {
        Material material = schemeService.queryMaterial(this.getUser(request).getUsercode(), projectCode, schemeCode,
                materialCode);
        List<SchemeResultData> list = resultService.queryResultRawDataByMaterial(this.getUser(request).getUsercode(),
                projectCode, schemeCode, materialCode);
        List<Object> rtnList = new LinkedList<Object>();
        rtnList.add(material);
        rtnList.add(list);
        ajaxMessage(rtnList);
    }

    /**
     * 加载素材信息&注视点数据
     */
    public void loadMaterialAndFixationData() throws Exception {
        Material material = schemeService.queryMaterial(this.getUser(request).getUsercode(), projectCode, schemeCode,
                materialCode);
        List<SchemeResultData> list = resultService.queryResultFixationDataByMaterial(this.getUser(request)
                .getUsercode(), projectCode, schemeCode, materialCode);
        this.renderData(material, list);
    }

    /**
     * 加载素材信息&(注视点数据 和 原始数据 )
     */
    public void loadMaterialAndData() throws Exception {
        UserInfoDto user = getUser(request);
        Material material = schemeService.queryMaterial(user.getUsercode(), projectCode, schemeCode,
                materialCode);
        List<SchemeResultData> list = resultService.queryResultDataByMaterial(user.getUsercode(),
                projectCode, schemeCode, materialCode);
        this.renderData(material, list);
    }

    /**
     * 加载被试数据(根据素材)
     */
    @Deprecated
    public void loadData() throws Exception {
        List<SchemeResultData> list = resultService.queryResultRawDataByMaterial(this.getUser(request).getUsercode(),
                projectCode, schemeCode, materialCode);
        ajaxMessage(list);
    }

    /**
     * 加载素材信息
     */
    @Deprecated
    public void loadMaterial() throws Exception {
        Material material = schemeService.queryMaterial(this.getUser(request).getUsercode(), projectCode, schemeCode,
                materialCode);
        ajaxMessage(material);
    }

    /**
     * 加载方案(屏幕宽度和高度)
     */
    @Deprecated
    public void loadScheme() throws Exception {
        Scheme scheme = schemeService.queryScheme(this.getUser(request).getUsercode(), projectCode, schemeCode);
        Scheme rtnScheme = new Scheme();
        rtnScheme.setWidth(scheme.getWidth());
        rtnScheme.setHeight(scheme.getHeight());
        rtnScheme.getMaterials().add(scheme.getMaterials().get(0));
        ajaxMessage(rtnScheme);
    }

    /**
     * 渲染数据内容
     *
     * @param material
     * @param list
     * @return void
     * @title 》renderData
     * @author admin
     * @date 2019-12-30 15:16
     * @since v1.0.1
     **/
    public void renderData(Material material, List<SchemeResultData> list) throws Exception {
        UserInfoDto user = getUser(request);

        // 查询点击事件
        List<EventModel> eventInfos = this.eventService.queryEventList(user.getUsercode(), projectCode, schemeCode);
        for (SchemeResultData data : list) {
            for (EventModel info : eventInfos) {
                if (data.getName().equalsIgnoreCase(info.getResultName()) && material.getCode().equalsIgnoreCase(info.getMaterialCode())) {
                    data.setDuration(Long.valueOf(info.getIntervalTime()));
                    break;
                } else {
                    data.setDuration(material.getDuration());
                }
            }
        }
        List<Object> rtnList = new LinkedList<Object>();
        rtnList.add(material);
        rtnList.add(list);
        ajaxMessage(rtnList);
    }

    /**
     * 弹窗修改被试信息
     *
     * @return
     */
    public String popModifyResult() throws Exception {
        scheme = schemeService.queryScheme(this.getUser(request).getUsercode(), projectCode, schemeCode);
        resultList = resultService.queryResultList(this.getUser(request).getUsercode(), projectCode, schemeCode);

        return "toPopModifyResult";
    }

    /**
     * 修改被试信息
     *
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public void modifyResult() throws Exception {
        String thePageResultList = request.getParameter("thePageResultList");
        this.resultList = (List<Result>) JacksonMapper.json2List(thePageResultList, Result.class);

        resultService.modifyResultList(this.getUser(request).getUsercode(), projectCode, schemeCode, resultList);

    }

    /**
     * 弹窗修改AOI信息
     *
     * @return
     */
    public String popModifyAoi() throws Exception {
        configList = AnalysisConfig.aoiConfigList;

        return "toPopModifyAoi";
    }

    public List<Map<String,String>> resultAnswer;

    public List<Map<String, String>> getResultAnswer() {
        return resultAnswer;
    }

    public void setResultAnswer(List<Map<String, String>> resultAnswer) {
        this.resultAnswer = resultAnswer;
    }

    public Map<String, Object> getKv() {
        return kv;
    }

    public void setKv(Map<String, Object> kv) {
        this.kv = kv;
    }

    public List<Question> getQuestionList() {
        return questionList;
    }

    public void setQuestionList(List<Question> questionList) {
        this.questionList = questionList;
    }

    public String popReportAoi() throws Exception {
        kv = new HashMap<String, Object>();
        String data = request.getParameter("aoiData");
        String resultNameStr = request.getParameter("resultName");
        resultNameStr = URLDecoder.decode(resultNameStr, "utf-8");
        List<ReportAoiData> listData = (List<ReportAoiData>) JacksonMapper.json2List(data, ReportAoiData.class);
        Map<String, String> map = (Map<String, String>) JacksonMapper.json2Bean(resultNameStr, Map.class);
        String name = map.get("name");

        String userCode = getUserCode();


        String key = userCode + CommonConstants.AnalysisConstats.CACHE_SPLIT + projectCode
                + CommonConstants.AnalysisConstats.CACHE_SPLIT + schemeCode;

        Scheme scheme = schemeService.queryScheme(userCode, projectCode, schemeCode);
        List<Result> results = resultService.queryResultList(userCode, projectCode, schemeCode);
        questionList = scheme.getQuestions();

        Result result = readResult(results, name);
        Map<String, String> answerMap = fill(result, questionList);
        resultAnswer.add(answerMap);


        reportList = new LinkedList<Map<String, Object>>();
        reportList.add(new HashMap<String, Object>() {{
            put("zb", "指标1");
            put("zs", "1");
            put("cs", "22");
            put("st", "0");
            put("et", "1");
        }});
        reportList.add(new HashMap<String, Object>() {{
            put("zb", "指标2");
            put("zs", "1");
            put("cs", "22");
            put("st", "0");
            put("et", "1");
        }});
        reportList.add(new HashMap<String, Object>() {{
            put("zb", "指标3");
            put("zs", "1");
            put("cs", "22");
            put("st", "0");
            put("et", "1");
        }});
        return "toPopReportAoi";
    }

    private Map<String,String> fill(Result result, List<Question> questionList){
        if (null == result){
            return null;
        }
        Map<String,String> map = new HashMap<String, String>();
        List<Answer> answers = result.getAnswers();
        for (Answer answer : answers){
            for (Question question :questionList){
                if (question.getNo().equals(answer.getNo())){
                    map.put(question.getName(),answer.getValue());
                }
            }
        }
        return map;
    }

    private Result readResult(List<Result> list, String name) {
        for (Result result : list) {
            if (result.getResultName().equals(name)) {
                return result;
            }
        }
        return null;
    }

    /**
     * 修改AOI信息
     *
     * @throws Exception
     */
    public void modifyAoi() throws Exception {
        String thePageAoiGraph = request.getParameter("thePageAoiGraph");
        AoiData aoiGraph = (AoiData) JacksonMapper.json2Bean(thePageAoiGraph, AoiData.class);

        schemeService.saveAoiData(this.getUser(request).getUsercode(), projectCode, schemeCode, aoiGraph);

    }

    /**
     * 保存AOI的图形
     *
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public void saveAoiGraphs() throws Exception {
        String aoiGraphs = request.getParameter("aoiGraphs");
        List<AoiData> aoiGraphsList = (List<AoiData>) JacksonMapper.json2List(aoiGraphs, AoiData.class);

        schemeService.syncAoiData(this.getUser(request).getUsercode(), projectCode, schemeCode, aoiGraphsList);
    }


    public void reMark() throws Exception {
        resultService.syncResultData(1, getUserCode(), projectCode, schemeCode, resultCode);
    }

    // ------------------------------------------以下是get/set方法-----------------------------------------
    public List<Project> getProjectList() {
        return projectList;
    }

    public void setProjectList(List<Project> projectList) {
        this.projectList = projectList;
    }

    public String getProjectName() {
        return projectName;
    }

    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }

    public String getProjectCode() {
        return projectCode;
    }

    public void setProjectCode(String projectCode) {
        this.projectCode = projectCode;
    }

    public String getSchemeCode() {
        return schemeCode;
    }

    public void setSchemeCode(String schemeCode) {
        this.schemeCode = schemeCode;
    }

    public List<Material> getMaterialList() {
        return materialList;
    }

    public void setMaterialList(List<Material> materialList) {
        this.materialList = materialList;
    }

    public String getResultCode() {
        return resultCode;
    }

    public void setResultCode(String resultCode) {
        this.resultCode = resultCode;
    }

    public String getMaterialCode() {
        return materialCode;
    }

    public void setMaterialCode(String materialCode) {
        this.materialCode = materialCode;
    }

    public String getTheSource() {
        return theSource;
    }

    public void setTheSource(String theSource) {
        this.theSource = theSource;
    }

    public Scheme getScheme() {
        return scheme;
    }

    public void setScheme(Scheme scheme) {
        this.scheme = scheme;
    }

    public List<AoiData> getAoiGraphsList() {
        return aoiGraphsList;
    }

    public void setAoiGraphsList(List<AoiData> aoiGraphsList) {
        this.aoiGraphsList = aoiGraphsList;
    }

    public List<AnalysisConfig> getConfigList() {
        return configList;
    }

    public String getAlreadyCheckboxs() {
        return alreadyCheckboxs;
    }

    public void setAlreadyCheckboxs(String alreadyCheckboxs) {
        this.alreadyCheckboxs = alreadyCheckboxs;
    }

    public String getAlreadyRadio() {
        return alreadyRadio;
    }

    public void setAlreadyRadio(String alreadyRadio) {
        this.alreadyRadio = alreadyRadio;
    }

    public List<Result> getResultList() {
        return resultList;
    }

    public void setResultList(List<Result> resultList) {
        this.resultList = resultList;
    }

    public String getUserCode() {
        return this.getUser(request).getUsercode(); // 用户编码直接从Session中返回
    }

    public int getHasLoad() {
        return hasLoad;
    }

    public void setHasLoad(int hasLoad) {
        this.hasLoad = hasLoad;
    }

    public List<Map<String, Object>> getReportList() {
        return reportList;
    }

    public void setReportList(List<Map<String, Object>> reportList) {
        this.reportList = reportList;
    }
}
